/*
 *所有关于boardInfo类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*boardInfoService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
using System.Linq;
using VOL.Core.Utilities;
using System.Linq.Expressions;
using VOL.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.RadarDevice.IRepositories;
using Newtonsoft.Json;
using VOL.Core.Configuration;
using VOL.Core.ManageUser;
using VOL.Entity.DomainModels.Devices.Dto;
using System.Text;
using System.Text.RegularExpressions;

namespace VOL.RadarDevice.Services
{
    public partial class boardInfoService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IboardInfoRepository _repository;//访问数据库
        private readonly IdeviceShareRepository _repositorySharp;//访问数据库

        [ActivatorUtilitiesConstructor]
        public boardInfoService(
            IboardInfoRepository dbRepository,
            IdeviceShareRepository repositorySharp,
            IHttpContextAccessor httpContextAccessor
            )
        : base(dbRepository)
        {
            _httpContextAccessor = httpContextAccessor;
            _repositorySharp = repositorySharp;
            _repository = dbRepository;
            //多租户会用到这init代码，其他情况可以不用
            //base.Init(dbRepository);
        }
        /// <summary>
        /// 列表查询
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public override PageGridData<boardInfo> GetPageData(PageDataOptions options)
        {
            var deviceNo = "";

            var listWhere = JsonConvert.DeserializeObject<List<OptionWheres>>(options.Wheres);
            foreach (var item in listWhere)
            {
                if (item.name == "deviceNo")
                    deviceNo = item.value;
            }

            int pageSize = options.Rows; // 每页显示的数量
            int pageIndex = options.Page; // 当前页码
            string sort = options.Sort;

            var querys = repository.FindAsIQueryable(r => 1 == 1).WhereIF(!string.IsNullOrWhiteSpace(deviceNo), d => d.deviceNo.Contains(deviceNo));

            var allowIds = AppSetting.QueryAllDeviceUserIds;
            if (!string.IsNullOrWhiteSpace(allowIds))
            {
                var userId = UserContext.Current.UserId;
                var strIds = allowIds.Split(',');
                var ids = Array.ConvertAll(strIds, int.Parse);
                if (!ids.Contains(userId))
                {
                    var sharpModels = _repositorySharp.FindAsIQueryable(r => 1 == 1).ToList();
                    List<deviceShare> shares = new List<deviceShare>();
                    foreach (var sharpModel in sharpModels)
                    {
                        var userIds = sharpModel.shareUserIds.Split(",");
                        if (userIds.Contains(userId.ToString()))
                        {
                            shares.Add(sharpModel);
                        }
                    }
                    var deviceIdList = shares.Select(r => r.deviceId).ToList();
                    querys = querys.Where(d => d.CreateID == userId || deviceIdList.Contains(d.device_id));
                }
            }
            var dtos = querys;
            if (options.Order == "desc")
                dtos = querys.OrderByDescending(d => d.updateTime).OrderByDescending(d => d.deviceNo).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            else
                dtos = querys.OrderBy(d => d.updateTime).OrderBy(d => d.deviceNo).Skip((pageIndex - 1) * pageSize).Take(pageSize);

            PageGridData<boardInfo> pageGridData = new PageGridData<boardInfo>();
            var models = dtos.ToList();

            pageGridData.rows = models;
            pageGridData.total = querys.ToList().Count;

            GetPageDataOnExecuted?.Invoke(pageGridData);
            return pageGridData;
        }
        /// <summary>
        /// 导出处理
        /// </summary>
        /// <param name="pageData"></param>
        /// <returns></returns>
        public override WebResponseContent Export(PageDataOptions pageData)
        {
            var deviceNo = "";

            var listWhere = JsonConvert.DeserializeObject<List<OptionWheres>>(pageData.Wheres);
            foreach (var item in listWhere)
            {
                if (item.name == "deviceNo")
                    deviceNo = item.value;
            }

            var querys = repository.FindAsIQueryable(r => 1 == 1).WhereIF(!string.IsNullOrWhiteSpace(deviceNo), d => d.deviceNo.Contains(deviceNo));

            var allowIds = AppSetting.QueryAllDeviceUserIds;
            if (!string.IsNullOrWhiteSpace(allowIds))
            {
                var userId = UserContext.Current.UserId;
                var strIds = allowIds.Split(',');
                var ids = Array.ConvertAll(strIds, int.Parse);
                if (!ids.Contains(userId))
                {
                    var sharpModels = _repositorySharp.FindAsIQueryable(r => 1 == 1).ToList();
                    List<deviceShare> shares = new List<deviceShare>();
                    foreach (var sharpModel in sharpModels)
                    {
                        var userIds = sharpModel.shareUserIds.Split(",");
                        if (userIds.Contains(userId.ToString()))
                        {
                            shares.Add(sharpModel);
                        }
                    }
                    var deviceIdList = shares.Select(r => r.deviceId).ToList();
                    querys = querys.Where(d => d.CreateID == userId || deviceIdList.Contains(d.device_id));
                }
            }
            var dtos = querys;
            if (pageData.Order == "asc")
                dtos = querys.OrderBy(d => d.updateTime).OrderBy(d => d.deviceNo);
            else
                dtos = querys.OrderByDescending(d => d.updateTime).OrderByDescending(d => d.deviceNo);
            var models = dtos.ToList();

            return base.MyExport(models);
        }
        /// <summary>
        /// 下发设备查询帧（主板）
        /// </summary>
        /// <param name="deviceNo">设备编号</param>
        /// <returns></returns>
        public async Task<WebResponseContent> SendBoardQueryFrame(string deviceNo)
        {
            if (string.IsNullOrWhiteSpace(deviceNo))
            {
                return new WebResponseContent().Error("设备编号不能为空！");
            }
            var userId = UserContext.Current.UserId;
            var user = UserContext.Current.GetUserInfo(userId);

            var url = $"{AppSetting.TcpServiceApiUrl}Radar/api/QueryBoardInfo?deviceNo={deviceNo}&userId={userId}&name={user.UserTrueName}";
            var resStr = await HttpGet(url);
            if (string.IsNullOrEmpty(resStr))
            {
                return new WebResponseContent().Error("指令添加异常");
            }
            var res = JsonConvert.DeserializeObject<ApiResult>(resStr);
            if (res.success)
            {
                return new WebResponseContent().OK("指令添加成功");
            }
            return new WebResponseContent().Error(res.message);
        }
        /// <summary>
        /// 发送设备设置指令
        /// </summary>
        /// <param name="saveDataModel"></param>
        /// <returns></returns>
        public override WebResponseContent Update(SaveModel saveDataModel)
        {
            if (saveDataModel.MainData.DicKeyIsNullOrEmpty("deviceNo"))
            {
                return new WebResponseContent().Error("设备编号不能为空！");
            }
            var deviceNo = saveDataModel.MainData["deviceNo"].ToString();
            var sendimode = saveDataModel.MainData["sendimode"].GetInt();
            var gatherInterval = saveDataModel.MainData["gatherInterval"].GetInt();
            var primaryIP = saveDataModel.MainData["primaryIP"].ToString();
            var secondaryIP = saveDataModel.MainData["secondaryIP"].ToString();
            var powerMode = saveDataModel.MainData["powerMode"].GetInt();
            var displaySwitch = saveDataModel.MainData["displaySwitch"].GetInt();
            var heartbeatInterval = saveDataModel.MainData["heartbeatInterval"].GetInt();

            var flag = IsValidIPPortFormat(primaryIP);
            if (!flag)
            {
                return new WebResponseContent().Error("主IP格式有误，正确格式如：100.1.100.100:9991");
            }
            flag = IsValidIPPortFormat(secondaryIP);
            if (!flag)
            {
                return new WebResponseContent().Error("副IP格式有误，正确格式如：100.1.100.100:9991");
            }
            boardInfoDto dto = new boardInfoDto()
            {
                deviceNo = deviceNo,
                sendimode = sendimode,
                gatherInterval = gatherInterval,
                primaryIP = primaryIP,
                secondaryIP = secondaryIP,
                powerMode = powerMode,
                displaySwitch = displaySwitch,
                heartbeatInterval = heartbeatInterval,
            };

            var userId = UserContext.Current.UserId;
            var user = UserContext.Current.GetUserInfo(userId);

            dto.Id = userId;
            dto.Name = user.UserTrueName;

            var jsonStr = JsonConvert.SerializeObject(dto);
            var url = AppSetting.TcpServiceApiUrl + "Radar/api/SetBoardInfo";
            var resStr = HttpPost(url, jsonStr).Result;
            if (string.IsNullOrEmpty(resStr))
            {
                return new WebResponseContent().Error("指令添加异常");
            }
            var res = JsonConvert.DeserializeObject<ApiResult>(resStr);
            if (res.success)
            {
                return new WebResponseContent().OK("指令添加成功");
            }
            return new WebResponseContent().Error(res.message);
        }
        public  bool IsValidIPPortFormat(string ipPort)
        {
            string pattern = @"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?):[0-9]{1,5}$";
            return Regex.IsMatch(ipPort, pattern);
        }
        #region HTTP请求
        /// <summary>
        /// http Get请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <returns></returns>
        public async Task<string> HttpGet(string url)
        {
            string resStr = "";
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    // 发送GET请求
                    HttpResponseMessage response = await client.GetAsync(url);
                    // 确保请求成功
                    response.EnsureSuccessStatusCode();

                    // 读取响应内容作为字符串
                    resStr = await response.Content.ReadAsStringAsync();
                }
                catch (HttpRequestException e)
                {
                    Console.WriteLine("Message :{0} ", e.Message);
                }
            }
            return resStr;
        }
        /// <summary>
        /// Http Post请求(参数Json)
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="param">请求参数(json)</param>
        /// <returns></returns>
        public async Task<string> HttpPost(string url, string param)
        {
            string resStr = "";
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    if (!string.IsNullOrEmpty(param))
                    {
                        // 将JSON字符串转换为HttpContent对象，并设置Content-Type为application/json
                        HttpContent content = new StringContent(param, Encoding.UTF8, "application/json");
                        // 发送POST请求
                        HttpResponseMessage response = await client.PostAsync(url, content);
                        // 确保请求成功
                        response.EnsureSuccessStatusCode();
                        resStr = await response.Content.ReadAsStringAsync();
                    }
                    else
                    {
                        HttpResponseMessage response = await client.PostAsync(url, null);
                        // 确保请求成功
                        response.EnsureSuccessStatusCode();
                        // 读取响应内容
                        resStr = await response.Content.ReadAsStringAsync();
                    }
                }
                catch (HttpRequestException e)
                {
                    Console.WriteLine("\nException Caught!");
                    Console.WriteLine("Message :{0} ", e.Message);
                }
            }
            return resStr;
        }
        #endregion HTTP请求
    }
}
